﻿using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using Model.Interfaces;
using Model.ModelEventArgs;

namespace Data.MappingClasses
{
    [TableAttribute(Name = "dbo.Town")]
    public partial class Town : AbstractMappingClass, INotifyPropertyChanging, INotifyPropertyChanged
    {
        public event EventHandler<ModelItemEventArgs> AddedStreetEvent;
        public event EventHandler<ModelItemEventArgs> RemovedStreetEvent;
        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

        private short _idTown;

        private string _nameTown;

        private short _refCountry;

        private EntitySet<Street> _Streets;

        private EntityRef<Country> _Country;

        #region Extensibility Method Definitions
        partial void OnLoaded();
        partial void OnValidate(System.Data.Linq.ChangeAction action);
        partial void OnCreated();
        partial void OnidTownChanging(short value);
        partial void OnidTownChanged();
        partial void OnnameTownChanging(string value);
        partial void OnnameTownChanged();
        partial void OnrefCountryChanging(short value);
        partial void OnrefCountryChanged();
        #endregion

        public Town()
        {
            this._Streets = new EntitySet<Street>(new Action<Street>(this.AttachStreets), new Action<Street>(this.DetachStreets));
            this._Country = default(EntityRef<Country>);
            OnCreated();
        }

        [ColumnAttribute(Storage = "_idTown", AutoSync = AutoSync.OnInsert, DbType = "SmallInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
        public short idTown
        {
            get
            {
                return this._idTown;
            }
            set
            {
                if ((this._idTown != value))
                {
                    this.OnidTownChanging(value);
                    this.SendPropertyChanging();
                    this._idTown = value;
                    this.SendPropertyChanged("idTown");
                    this.OnidTownChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_nameTown", DbType = "VarChar(100) NOT NULL", CanBeNull = false)]
        public string nameTown
        {
            get
            {
                return this._nameTown;
            }
            set
            {
                if ((this._nameTown != value))
                {
                    this.OnnameTownChanging(value);
                    this.SendPropertyChanging();
                    this._nameTown = value;
                    this.SendPropertyChanged("nameTown");
                    this.OnnameTownChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_refCountry", DbType = "SmallInt NOT NULL")]
        public short refCountry
        {
            get
            {
                return this._refCountry;
            }
            set
            {
                if ((this._refCountry != value))
                {
                    if (this._Country.HasLoadedOrAssignedValue)
                    {
                        throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefCountryChanging(value);
                    this.SendPropertyChanging();
                    this._refCountry = value;
                    this.SendPropertyChanged("refCountry");
                    this.OnrefCountryChanged();
                }
            }
        }

        [AssociationAttribute(Name = "Town_Street", Storage = "_Streets", ThisKey = "idTown", OtherKey = "refTown")]
        public EntitySet<Street> Streets
        {
            get
            {
                return this._Streets;
            }
            set
            {
                this._Streets.Assign(value);
            }
        }

        [AssociationAttribute(Name = "Country_Town", Storage = "_Country", ThisKey = "refCountry", OtherKey = "idCountry", IsForeignKey = true)]
        public Country Country
        {
            get
            {
                return this._Country.Entity;
            }
            set
            {
                Country previousValue = this._Country.Entity;
                if (((previousValue != value)
                     || (this._Country.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._Country.Entity = null;
                        previousValue.Towns.Remove(this);
                    }
                    this._Country.Entity = value;
                    if ((value != null))
                    {
                        value.Towns.Add(this);
                        this._refCountry = value.idCountry;
                    }
                    else
                    {
                        this._refCountry = default(short);
                    }
                    this.SendPropertyChanged("Country");
                }
            }
        }

        public event PropertyChangingEventHandler PropertyChanging;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }

        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void AttachStreets(Street entity)
        {
            this.SendPropertyChanging();
            entity.Town = this;
        }

        private void DetachStreets(Street entity)
        {
            this.SendPropertyChanging();
            entity.Town = null;
        }

        public override Model.ModelClasses.AbstractModel PureModel
        {
            get
            {
                return base.PureModel;
            }
            set
            {
                if(_pureModel != null)
                {
                    _pureModel.UpdateModelEvent -= UpdateModelEventHandler;
                    ((Model.ModelClasses.Town) _pureModel).Streets.AddedItemEvent -= AddedItemEventHandler;
                    ((Model.ModelClasses.Town)_pureModel).Streets.RemovedItemEvent -= RemovedItemEventHandler;
                }
            }
        }

        private void RemovedItemEventHandler(object sender, ModelItemEventArgs e)
        {
            RemovedStreetEvent(this, e);
        }

        private void AddedItemEventHandler(object sender, ModelItemEventArgs e)
        {
            AddedStreetEvent(this, e);
        }

        private void UpdateModelEventHandler(object sender, EventArgs e)
        {
            nameTown = ((ITown) _pureModel).Name;
            UpdateData();
        }
    }
}